﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GSPatEditor.Pat
{
    class Palette
    {
        public static Palette CreateFromFile(string file)
        {
            if (!File.Exists(file))
            {
                return null;
            }
            return new Palette(file);
        }

        public Color GetColorFromIndex(int index)
        {
            return colors[index];
        }

        private Color[] colors;
        private int trans_id;

        public Palette(string fn)
        {
            using (FileStream stream = File.OpenRead(fn))
            {
                colors = new Color[256];
                stream.ReadByte();
                byte[] buffer = new byte[2];
                for (int i = 0; i < colors.Length; ++i)
                {
                    stream.Read(buffer, 0, 2);
                    colors[i] = FromBGRA5551(BitConverter.ToInt16(buffer, 0));
                    if (colors[i].A == 0)
                    {
                        trans_id = i;
                    }
                }
            }
        }

        public void WriteToFile(string fn)
        {
            using (FileStream stream = File.Open(fn, FileMode.CreateNew))
            {
                stream.Write(new byte[] { 0x10 }, 0, 1);
                for (int i = 0; i < colors.Length; ++i)
                {
                    stream.Write(BitConverter.GetBytes(ToBGRA5551(colors[i])), 0, 2);
                }
            }
        }

        public Palette(Color[] colors, int trans_id)
        {
            this.colors = colors;
            this.trans_id = trans_id;
        }

        private static Color FromBGRA5551(Int16 val)
        {
            int b = (val & ((1 << 5) - 1)) >> 0 << 3;
            int g = (val & ((1 << 10) - 1)) >> 5 << 3;
            int r = (val & ((1 << 15) - 1)) >> 10 << 3;
            int a = ((val & (1 << 15)) != 0) ? 255 : 0;
            return Color.FromArgb(a, r, g, b);
        }

        private static Int16 ToBGRA5551(Color c)
        {
            int b = (c.B & 0xF8) >> 3;
            int g = (c.G & 0xF8) >> 3;
            int r = (c.R & 0xF8) >> 3;
            int a = c.A == 0 ? 0 : 1;
            return (Int16)(b | g << 5 | r << 10 | a << 15);
        }

        public int TryFindColor(Color c)
        {
            for (int i = 0; i < colors.Length; ++i)
            {
                if (colors[i] == c)
                {
                    return i;
                }
            }
            return trans_id;
        }
    }
}
